Skip to content

feat: Add SQLAlchemy models for Chancy tables#83

Open
njg7194 wants to merge 1 commit into
TkTech:26_uxfrom
njg7194:feature/sqlalchemy-models
Open

feat: Add SQLAlchemy models for Chancy tables#83
njg7194 wants to merge 1 commit into
TkTech:26_uxfrom
njg7194:feature/sqlalchemy-models

Conversation

@njg7194

@njg7194 njg7194 commented Feb 1, 2026

Copy link
Copy Markdown

Summary

This PR adds SQLAlchemy models as a new contrib module, mirroring the existing Django models. This addresses #75.

Changes

  • chancy/contrib/sqlalchemy/init.py - Module documentation
  • chancy/contrib/sqlalchemy/models.py - SQLAlchemy models for Job, Worker, and Queue tables
  • tests/contrib/sqlalchemy/test_models.py - Integration tests

Features

  • Full SQLAlchemy 2.0 style with mapped_column and Mapped types
  • PostgreSQL-specific types (JSONB, ARRAY, UUID)
  • Table prefix customization via CHANCY_PREFIX environment variable
  • Comprehensive docstrings with usage examples
  • Unmanaged models (Chancy handles migrations)

Usage Example

from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
from chancy.contrib.sqlalchemy.models import Job, Queue, Worker

engine = create_engine("postgresql://...")

with Session(engine) as session:
    # Get all pending jobs
    pending_jobs = session.execute(
        select(Job).where(Job.state == "pending")
    ).scalars().all()
    
    # Get all active queues
    active_queues = session.execute(
        select(Queue).where(Queue.state == "active")
    ).scalars().all()

Closes #75

This adds a new contrib module with SQLAlchemy models that mirror the
existing Django models. Users can now query Chancy data using SQLAlchemy's
ORM without managing the table schema.

New files:
- chancy/contrib/sqlalchemy/__init__.py - Module docstring
- chancy/contrib/sqlalchemy/models.py - Job, Worker, Queue models
- tests/contrib/sqlalchemy/test_models.py - Integration tests

The models support:
- Table prefix customization via CHANCY_PREFIX environment variable
- Full SQLAlchemy 2.0 style with mapped_column and Mapped types
- PostgreSQL-specific types (JSONB, ARRAY, UUID)
- Comprehensive docstrings with usage examples

Closes TkTech#75
@TkTech TkTech self-requested a review February 2, 2026 00:36
@TkTech TkTech added the enhancement New feature or request label Feb 2, 2026
@TkTech TkTech changed the base branch from main to 26_ux February 2, 2026 00:36

@PaulM5406 PaulM5406 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @njg7194 for the PR. I will let @TkTech review the implementation details more thoroughly. Reading it, I have a few small comments.


with Session(engine) as session:
# Get all pending jobs
pending_jobs = session.query(Job).filter(Job.state == "pending").all()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this documentation uses the former SQLA syntaxe, i.e. session.query.
test_models.py uses modern syntaxe session.execute though.

PG_UUID(as_uuid=True),
primary_key=True,
)
queue: Mapped[str] = mapped_column(Text, nullable=False)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For the whole file, nullable can be inferred from the type.

Suggested change
queue: Mapped[str] = mapped_column(Text, nullable=False)
queue: Mapped[str] = mapped_column(Text)

If Optional is used, nullable=True is inferred.

"""

__tablename__ = f"{PREFIX}jobs"
__table_args__ = {"extend_existing": True}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is really useful ?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new chancy.contrib.sqlalchemy contrib module providing SQLAlchemy ORM models intended to map onto Chancy’s existing PostgreSQL tables (similar to the existing Django unmanaged models), along with integration tests to validate basic querying.

Changes:

  • Added chancy.contrib.sqlalchemy module and initial ORM model definitions for Job, Queue, and Worker.
  • Added integration tests that create Chancy records and query them via SQLAlchemy.
  • Added module-level documentation and usage examples.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 20 comments.

File Description
chancy/contrib/sqlalchemy/__init__.py Adds module documentation for the SQLAlchemy contrib package.
chancy/contrib/sqlalchemy/models.py Introduces SQLAlchemy declarative models intended to match Chancy core tables.
tests/contrib/sqlalchemy/test_models.py Adds integration tests to validate ORM querying against the Chancy test database.
tests/contrib/sqlalchemy/__init__.py Adds test package init file for SQLAlchemy contrib tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +33 to +40
# Create a queue using Chancy
await chancy.push_queue(
chancy.Queue(
name="test-sqlalchemy-queue",
concurrency=5,
polling_interval=10,
)
)
Comment on lines +57 to +63
# Ensure queue exists
await chancy.push_queue(
chancy.Queue(
name="test-job-queue",
concurrency=1,
)
)
Comment on lines +87 to +93
# Ensure queue exists
await chancy.push_queue(
chancy.Queue(
name="test-filter-queue",
concurrency=1,
)
)
Comment on lines +117 to +120
"""Test Job model __repr__ method."""
await chancy.push_queue(
chancy.Queue(name="repr-test-queue", concurrency=1)
)
Comment on lines +138 to +141
"""Test Queue model __repr__ method."""
await chancy.push_queue(
chancy.Queue(name="repr-queue", concurrency=1)
)
Comment on lines +15 to +17
return create_engine(
"postgresql://postgres:localtest@localhost:8190/postgres"
)
Comment on lines +66 to +71
job = await chancy.push(
chancy.Job.from_func(
"tests.contrib.sqlalchemy.test_models.dummy_job",
queue="test-job-queue",
kwargs={"message": "hello"},
)
Comment on lines +97 to +102
await chancy.push(
chancy.Job.from_func(
"tests.contrib.sqlalchemy.test_models.dummy_job",
queue="test-filter-queue",
kwargs={"index": i},
)
Comment on lines +122 to +126
job = await chancy.push(
chancy.Job.from_func(
"tests.contrib.sqlalchemy.test_models.dummy_job",
queue="repr-test-queue",
)
Comment on lines +5 to +10
import pytest
from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session

from chancy.contrib.sqlalchemy.models import Base, Job, Queue, Worker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: sqlalchemy models

4 participants